home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Tutorial / Cookbook / 41.PieChart / PieView.m < prev    next >
Text File  |  1995-06-12  |  8KB  |  361 lines

  1.  
  2. /* Generated by Interface Builder */
  3.  
  4. #import "PieView.h"
  5. #import "stdio.h"
  6. #import <dpsclient/wraps.h>
  7. #import <appkit/Font.h>
  8. #import <appkit/Application.h>
  9. #import <appkit/Pasteboard.h>
  10. #import <appkit/Cell.h>
  11. #import <appkit/Matrix.h>
  12. #import <appkit/Slider.h>
  13. #import <appkit/OpenPanel.h>
  14. #import <appkit/Panel.h>
  15. #import <appkit/Control.h>
  16. #import <appkit/Form.h>
  17. #import <strings.h>
  18. #import "slice.h"
  19. #import "math.h"
  20.  
  21. @implementation PieView
  22.  
  23. static char logString[10000];
  24.  
  25. +newFrame:(const NXRect *)tF
  26. {
  27.    int i;
  28.    char buf[4];
  29.    int used;
  30.    FILE *fd;
  31.    
  32.    // we are using the Appkit "newFrame" plus our own additions
  33.    self = [super newFrame:tF];
  34.    
  35.    numDrawSegments = 2;
  36.  
  37.    gray[0] = .333;
  38.    gray[1] = .666;
  39.    
  40.    strcpy(displayLabel[0],"/");
  41.    strcpy(displayLabel[1],"free");
  42.  
  43.     /* kludge becuase there is no UNIX documentation on the
  44.      * system call to get disk free space
  45.      */
  46.      
  47.     system("df / | tail -1 | awk '{print $5}' >/tmp/root_space_used");
  48.     fd = (FILE *) openFileReadOnly("/tmp/root_space_used");
  49.         fgets(buf, 4, fd);
  50.     sscanf(buf, "%d", &used);
  51.     fclose(fd);
  52.  
  53.    displayValue[0] = (float) used;
  54.    displayValue[1] = (float) (100 - used);
  55.    norm[0] = displayValue[0]*3.6;
  56.    norm[1] = displayValue[1]*3.6;
  57.   
  58.  
  59.    myFont = [Font newFont:"Helvetica"
  60.                   size:10.0
  61.           style:0
  62.           matrix:NX_IDENTITYMATRIX];
  63.           
  64.  
  65.    pieSize = 200.0;
  66.    pieFontSize = 10.0;
  67.    openReq = [OpenPanel new];
  68.    c_x = bounds.size.width/2.0;
  69.    c_y = bounds.size.height/2.0;
  70.    [self translate:c_x :c_y];
  71.    return self;
  72. }
  73.  
  74. - showError: (char *)errorMessage
  75. {
  76.   NXRunAlertPanel("Pie_Matrix", errorMessage,"OK",NULL,NULL);
  77. }
  78.  
  79. // --------------- methods that respond to user actions start here  --------------
  80.  
  81. - getValue:sender
  82. {
  83.     int i;
  84.     i = [sender selectedRow];
  85.     displayValue[i] = [sender floatValue];
  86.     // printf("Row = %d  Value = %f\n", i, displayValue[i]);
  87.     [self display];
  88.     return self;
  89. }
  90.  
  91. - getLabel:sender
  92. {
  93.     int i;
  94.     i = [sender selectedRow];
  95.     strcpy(displayLabel[i],[sender stringValue]);
  96.     // printf("Row = %d  String = %s\n", i, displayLabel[i]);
  97.     [self display];
  98.     return self;
  99. }
  100.  
  101. - getnSlices:sender
  102. {
  103.     numDrawSegments = [sender intValue];
  104.     [self display];
  105.     return self;
  106. }
  107.  
  108. - getPieSize:sender
  109. {
  110.     pieSize = [sender floatValue];
  111.     [pieSizeText setFloatValue:pieSize];
  112.     [self display];
  113.     return self;
  114. }
  115.  
  116. - getPieFontSize:sender
  117. {
  118.     pieFontSize = [sender floatValue];
  119.     myFont = [Font newFont:"Helvetica"
  120.                   size:pieFontSize
  121.           style:0
  122.           matrix:NX_IDENTITYMATRIX];
  123.     [pieFontText setFloatValue:pieFontSize];
  124.     [self display];
  125.     return self;
  126. }
  127.  
  128. - printDisplayList:sender
  129. {
  130. int i;
  131.     printf("Display List:\n");
  132.     for (i=0; i<numDrawSegments; i++) {
  133.         printf("%7.0f  %s\n", displayValue[i], displayLabel[i]);
  134.     }
  135.     return self;
  136. }
  137.  
  138. - printTree:sender
  139. {
  140.     printf("Tree Structure:\n");
  141.     treeprint(root, 0);
  142.     return self;
  143. }
  144.  
  145.  
  146. - openRequest:sender
  147. {
  148.     const char *fileName;
  149.     const char *const types[4] = {NULL,NULL};
  150.     int ok;
  151.  
  152.     if ([openReq runModalForTypes:types] && (fileName =[openReq filename])) {
  153.     [self openFile:fileName];
  154.     }
  155.     else
  156.     [self showError:"No file chosen or could not open file"];
  157.     return self;
  158. }
  159.  
  160. - copy:sender { 
  161.    id pb = [NXApp pasteboard];  /* global Pasteboard object */ 
  162.    NXStream  *st;               /* stream to collect data in */ 
  163.    char      *data;             /* actual data buffer */ 
  164.    int       length;            /* length of data */ 
  165.    int       maxLength;         /* (not used here) */
  166.  
  167.    // To see how to use the pasteboard see page 10-33 of
  168.    // the SysRefMan
  169.    // declare that we will supply a single type of data: PostScript
  170.    [pb declareTypes:&NXPostScriptPboard num:1 owner:self];
  171.  
  172.    /* get a stream which writes to memory */ 
  173.    st = NXOpenMemory( NULL, 0, NX_WRITEONLY );
  174.  
  175.    /* write PostScript code for this view into the stream */ 
  176.    [self copyPSCodeInside:NULL to:st];
  177.  
  178.    /* get actual data buffer from stream */ 
  179.    NXGetMemoryBuffer( st, &data, &length, &maxLength );
  180.  
  181.    /* write PostScript data to pasteboard */ 
  182.    [pb writeType:NXPostScriptPboard data:data length:length];
  183.  
  184.    /* deallocate stream, including its buffer */ 
  185.    NXCloseMemory( st, NX_FREEBUFFER );
  186.  
  187.    return self; 
  188. }
  189.  
  190.  
  191. // ---------------- Outlets start here ------------------
  192.  
  193. - setXForm:anObject
  194. {
  195.     xForm = anObject;
  196.     return self;
  197. }
  198.  
  199. - setYForm:anObject
  200. {
  201.     yForm = anObject;
  202.     return self;
  203. }
  204.  
  205. - setPieSizeText:anObject
  206. {
  207.     pieSizeText = anObject;
  208.     return self;
  209. }
  210.  
  211. - setPieFontText:anObject
  212. {
  213.     pieFontText = anObject;
  214.     return self;
  215. }
  216.  
  217. -(int) openFile:(const char *)fileName
  218. {
  219.   int i=0;
  220.   char buf[MAX_CHARS_PER_LINE], tmpStr[MAX_CHARS_PER_LINE];
  221.   FILE *input_fp;
  222.   float total=0.0;
  223.   int ret=0;
  224.   
  225.   if (( input_fp = fopen(fileName, "r") ) == NULL ) {
  226.      [self showError:"Could not open file"];
  227.      fprintf(stderr, "File: %s Could not be opened.\n", fileName);
  228.      return NO;
  229.   }
  230.  
  231.     /* initialize root value of tree */
  232.     root = createNode("/", 0);
  233.     root->stop = NO;
  234.  
  235.      while (fgets(buf, MAX_CHARS_PER_LINE, input_fp) != NULL) {
  236.         if (i >= MAX_LINES) {
  237.             printf("Too many lines\n");
  238.             break;
  239.         }
  240.         if (strlen(buf) == 1) {
  241.             printf("Blank Line\n");
  242.             break;
  243.         }
  244.         ret = sscanf(buf, "%f %s", &displayValue[i], displayLabel[i]);
  245.         if (ret == 1) {
  246.             root->word = strdup("/");
  247.             root->value = displayValue[i];
  248.          } else {
  249.             /* printf("In: %f %s\n", displayValue[i], displayLabel[i]); */
  250.             addtree(root, displayLabel[i], displayValue[i]);
  251.             i++;
  252.          }
  253.       }
  254.     numDataLines = i;
  255.     printf("%d data points read\n\n", numDataLines);
  256.     fclose(input_fp);
  257.     numDrawSegments = buildDisplayList(root, 0, 0, "/");
  258.     normalize(displayValue, norm, 360, numDrawSegments);
  259.     for (i=0; i<numDrawSegments; i++) {
  260.         angle[i] = norm[i] + total;
  261.         total += norm[i];
  262.     }
  263.     [self display];
  264.     return YES;
  265. }
  266.  
  267. /* make this view accept first responder so it will understand copy */
  268. -(BOOL)acceptsFirstResponder
  269. {
  270.     return (YES);
  271. }
  272.  
  273. -resignFirstResponder
  274. {
  275.     return self;
  276. }
  277.  
  278. - drawSelf:(NXRect*)r :(int)c
  279. {
  280.     int i;
  281.     float total = 0.0;
  282.     c_x = bounds.size.width/2.0 + bounds.origin.x;
  283.     c_y = bounds.size.height/2.0 + bounds.origin.y;
  284.     [self translate:c_x :c_y];
  285.     [myFont set];
  286.     PSsetgray(1.0);
  287.     NXRectFill(&bounds);
  288.     PSsetgray(0.0);
  289.     for (i=0; i<numDrawSegments; i++)
  290.     {
  291.      drawSlice(gray[i], pieSize, total, total+norm[i], pieFontSize, displayLabel[i]);
  292.        total = total + norm[i];
  293.     }
  294.     return self;
  295. }
  296.  
  297. // mouse handeling starts here
  298.  
  299. static char logString[10000];
  300.  
  301. /* add a string to the log and have text updated */
  302. static void addStringLog(target, string)
  303. char *string;
  304. id target;
  305. {
  306.     strcat(logString, string);
  307.     [target setStringValue:logString];
  308. }
  309.  
  310. /* add an event to the log text */
  311. static void addEventLog(target, string, x, y, type)
  312. char *string;
  313. id target;
  314. float x,y;
  315. int type;
  316. {
  317. static char tmpString[100];
  318.     strcat(logString, string);
  319.     if (type == 1) strcat(logString, " DOWN ");
  320.        else if (type == 2) strcat(logString, " UP ");
  321.           else if (type == 6) strcat(logString, " DRAG ");
  322.              else {
  323.                sprintf(tmpString, " type=%d ", type);
  324.                strcat(logString, tmpString);
  325.              }
  326.     sprintf(tmpString, "at x=%3.0f  y=%3.0f\n", x, y);
  327.     strcat(logString, tmpString);
  328.     [target setStringValue:logString];
  329. }
  330.  
  331. // from chapter 7 page 61
  332. - mouseDown:(NXEvent *)thisEvent
  333. {
  334.     register int i=0; 
  335.     NXPoint    Loc;
  336.     float mouseAngle, total=0.0;
  337.     Treeptr p;
  338.     
  339.     // printf("click type = %d\n", data.mouse.click);
  340.     Loc = thisEvent->location;
  341.     [self convertPoint:&Loc fromView:nil];
  342.     mouseAngle = 180.0/3.14158*atan(Loc.y/Loc.x);
  343.     if (Loc.x < 0.0)
  344.         mouseAngle = mouseAngle + 180.0;
  345.     if ((Loc.x > 0.0)  && (Loc.y < 0.0))
  346.         mouseAngle = mouseAngle + 360.0;
  347.     while (mouseAngle > angle[i])
  348.        i++;
  349.     p = locateInTree(root, displayLabel[i]);
  350.     numDrawSegments = buildDisplayList(root, 0, 0, "/");
  351.     normalize(displayValue, norm, 360, numDrawSegments);
  352.     for (i=0; i<numDrawSegments; i++) {
  353.         angle[i] = norm[i] + total;
  354.         total += norm[i];
  355.     }
  356.     [self display];
  357.     return(self); 
  358. }
  359. @end
  360.  
  361.